<template>
  <div class="register">
    <el-form ref="formRef" :model="form" :rules="rules" size="large">
      <el-form-item prop="name">
        <el-input
          v-model="form.name"
          :placeholder="$t('register.name')"
          show-word-limit
          clearable
        />
      </el-form-item>
      <el-form-item prop="captchaCode">
        <div class="flex justify-between items-center w-full">
          <el-input
            style="width: 65%"
            v-model="form.captchaCode"
            :placeholder="$t('register.captchaCode')"
          />
          <img
            class="flex-1 h-[40px] cursor-pointer ml-2"
            :src="captchaBase64"
            @click="getCaptcha"
            alt="验证码"
          />
        </div>
      </el-form-item>
      <el-form-item prop="validCode">
        <div class="flex justify-between items-center w-full">
          <el-input
            style="width: 65%"
            v-model="form.validCode"
            :placeholder="$t('register.validCode')"
            show-word-limit
            clearable
          />
          <el-button
            v-if="time !== 60"
            class="flex-1 h-[40px] cursor-pointer ml-2"
            type="info"
            disabled
          >
            {{ $t("register.validCodeTime", { time }) }}
          </el-button>
          <el-button
            v-else
            class="flex-1 h-[40px] cursor-pointer ml-2"
            type="primary"
            @click="getValidCode"
          >
            {{ $t("register.getValidCode") }}
          </el-button>
        </div>
      </el-form-item>
      <el-form-item prop="nickName">
        <el-input
          v-model="form.nickName"
          :placeholder="$t('register.nickName')"
          show-word-limit
          clearable
          autocomplete="off"
        />
      </el-form-item>
      <el-form-item prop="pwd">
        <el-input
          v-model="form.pwd"
          :placeholder="$t('register.pwd')"
          type="password"
          show-password
          show-word-limit
          clearable
          autocomplete="new-password"
        />
      </el-form-item>
      <el-form-item prop="repeatPwd">
        <el-input
          v-model="form.repeatPwd"
          :placeholder="$t('register.repeatPwd')"
          type="password"
          show-password
          show-word-limit
          clearable
        />
      </el-form-item>
      <el-button
        :loading="loading"
        type="primary"
        class="w-full"
        @click.prevent="handleRegister"
      >
        {{ $t("register.register") }}
      </el-button>
    </el-form>
  </div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";

import { ElMessage } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";

import { useUserStore } from "@/stores";
import type {
  LoginResult,
  RegisterReq,
  SendValidCodeReq,
} from "@/api/auth/types";
import { getCaptchaApi, sendcode } from "@/api/auth";
import { vueMetaEnv } from "@/settings";
import { validateEmail, validatePhoneNumber } from "@/utils/validation_utils";

const router = useRouter();
const userStore = useUserStore();
const { t } = useI18n();

const props = defineProps({
  emit: {
    type: Boolean,
    default: false,
  },
});

// 图形验证
const captchaBase64 = ref<string>("");
const getCaptcha = () => {
  getCaptchaApi().then(({ data }) => {
    form.value.captchaId = data.captchaId;
    captchaBase64.value = data.base64Image;
  });
};
getCaptcha();

const formRef = ref<FormInstance>();
const form = ref<RegisterReq>({
  captchaCode: "",
  // 用于检测重复请求的唯一字符串ID
  requestId: Math.random() * 10 + "",
  // 手机号/邮箱
  name: "",
  // 手机号/邮箱的验证码
  validCode: "",
  // 昵称
  nickName: "",
  // 密码
  pwd: "",
  // 确认密码
  repeatPwd: "",
});

// 手机号校验
const mobileValidate = (rule: any, value: any, callback: any) => {
  if (!value) {
    callback(new Error(t("register.nameRequired")));
  } else {
    if (!validatePhoneNumber(value) && !validateEmail(value)) {
      callback(new Error(t("register.phoneOrEmailError")));
    } else {
      callback();
    }
  }
};

// 密码校验
const pwdValidate = (rule: any, value: any, callback: any) => {
  const ISPWD =
    /^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%?^&*,\._\+(){}])[0-9a-zA-Z!@#$%?^&*,\\._\+(){}]{8,20}$/; // eslint-disable-line
  if (value === "") {
    callback(new Error(t("register.pwdRequired")));
  } else if (!ISPWD.test(value)) {
    callback(new Error(t("register.pwdRules")));
  } else {
    callback();
  }
};

// 确认密码校验
const confirmPwdValidate = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error(t("register.repeatPwdRequired")));
  } else if (value !== form.value.pwd) {
    callback(new Error(t("register.comparePwd")));
  } else {
    callback();
  }
};

const rules = reactive<FormRules<RegisterReq>>({
  name: [
    {
      required: true,
      validator: mobileValidate,
      trigger: "blur",
    },
  ],
  captchaCode: [
    {
      required: true,
      message: t("register.captchaCodeRequired"),
      trigger: "blur",
    },
  ],
  validCode: [
    {
      required: true,
      message: t("register.validCodeRequired"),
      trigger: "blur",
    },
  ],
  nickName: [
    {
      required: true,
      message: t("register.nickNameRequired"),
      trigger: "blur",
    },
  ],
  pwd: [{ required: true, validator: pwdValidate, trigger: "blur" }],
  repeatPwd: [
    { required: true, validator: confirmPwdValidate, trigger: "blur" },
  ],
});

const time = ref(60);
const interval = ref<number | null>(null);
const getValidCode = () => {
  if (time.value !== 60) return;
  formRef.value?.validateField(["name", "captchaCode"], async (valid) => {
    if (!valid) return;
    const codeForm: SendValidCodeReq = {
      name: form.value.name,
      captchaId: form.value.captchaId as string,
      captchaCode: form.value.captchaCode as string,
      tenant: useUserStore().user.tenant,
      sendValidCode: true,
      directoryId: vueMetaEnv.APP_DIRECTORY_ID as string,
      product: vueMetaEnv.APP_PRODUCT as string,
    };
    await sendcode(codeForm);
    ElMessage.success("验证码发送成功，请注意查收！");
    interval.value = setInterval(() => {
      if (time.value <= 0 && interval.value) {
        clearInterval(interval.value);
        time.value = 60;
        return;
      }
      time.value--;
    }, 1000);
  });
};

const loading = ref(false);
const emits = defineEmits(["register"]);
const handleRegister = () => {
  formRef.value?.validate((valid: boolean) => {
    if (!valid) return;
    loading.value = true;
    delete form.value.captchaId;
    delete form.value.captchaCode;
    userStore
      .register(form.value)
      .then((data: LoginResult) => {
        if (props.emit) {
          emits("register", data);
          return;
        }
        router.push({ path: "/" });
      })
      .finally(() => {
        loading.value = false;
      });
  });
};
</script>
<style lang="scss" scoped>
img {
  display: block;
}
</style>
